﻿using System.Collections.Generic;
using System.Collections;
using System.Reflection;
using System.ComponentModel;
namespace System.Web
{
    public partial class NetHttpApplication : IDisposable
    {
        private EventArgs _appEvent;
        private NetHttpAsyncResult _ar;
        private AsyncAppEventHandlersTable _asyncEvents;
        private EventHandlerList _events;

        private static readonly object EventAcquireRequestState = new object();
        private static readonly object EventAuthenticateRequest = new object();
        private static readonly object EventAuthorizeRequest = new object();
        private static readonly object EventBeginRequest = new object();
        private static readonly object EventDefaultAuthentication = new object();
        private static readonly object EventDisposed = new object();
        private static readonly object EventEndRequest = new object();
        private static readonly object EventErrorRecorded = new object();
        private static readonly object EventLogRequest = new object();
        private static readonly object EventMapRequestHandler = new object();
        private static readonly object EventPostAcquireRequestState = new object();
        private static readonly object EventPostAuthenticateRequest = new object();
        private static readonly object EventPostAuthorizeRequest = new object();
        private static readonly object EventPostLogRequest = new object();
        private static readonly object EventPostMapRequestHandler = new object();
        private static readonly object EventPostReleaseRequestState = new object();
        private static readonly object EventPostRequestHandlerExecute = new object();
        private static readonly object EventPostResolveRequestCache = new object();
        private static readonly object EventPostUpdateRequestCache = new object();
        private static readonly object EventPreRequestHandlerExecute = new object();
        private static readonly object EventPreSendRequestContent = new object();
        private static readonly object EventPreSendRequestHeaders = new object();
        private static readonly object EventReleaseRequestState = new object();
        private static readonly object EventResolveRequestCache = new object();
        private static readonly object EventUpdateRequestCache = new object();

        internal class ArglessEventHandlerProxy
        {
            private MethodInfo _arglessMethod;
            private object _target;

            internal ArglessEventHandlerProxy(object target, MethodInfo arglessMethod)
            {
                _target = target;
                _arglessMethod = arglessMethod;
            }

            internal void Callback(object sender, EventArgs e)
            {
                _arglessMethod.Invoke(_target, new object[0]);
            }

            internal EventHandler Handler
            {
                get { return new EventHandler(Callback); }
            }
        }

        public event EventHandler AcquireRequestState
        {
            add { AddSyncEventHookup(EventAcquireRequestState, value, RequestNotification.AcquireRequestState); }
            remove { RemoveSyncEventHookup(EventAcquireRequestState, value, RequestNotification.AcquireRequestState); }
        }

        public event EventHandler AuthenticateRequest
        {
            add { AddSyncEventHookup(EventAuthenticateRequest, value, RequestNotification.AuthenticateRequest); }
            remove { RemoveSyncEventHookup(EventAuthenticateRequest, value, RequestNotification.AuthenticateRequest); }
        }

        public event EventHandler AuthorizeRequest
        {
            add { AddSyncEventHookup(EventAuthorizeRequest, value, RequestNotification.AuthorizeRequest); }
            remove { RemoveSyncEventHookup(EventAuthorizeRequest, value, RequestNotification.AuthorizeRequest); }
        }

        public event EventHandler BeginRequest
        {
            add { AddSyncEventHookup(EventBeginRequest, value, RequestNotification.BeginRequest); }
            remove { RemoveSyncEventHookup(EventBeginRequest, value, RequestNotification.BeginRequest); }
        }

        internal event EventHandler DefaultAuthentication
        {
            add { AddSyncEventHookup(EventDefaultAuthentication, value, RequestNotification.AuthenticateRequest); }
            remove { RemoveSyncEventHookup(EventDefaultAuthentication, value, RequestNotification.AuthenticateRequest); }
        }

        public event EventHandler Disposed
        {
            add { Events.AddHandler(EventDisposed, value); }
            remove { Events.RemoveHandler(EventDisposed, value); }
        }

        public event EventHandler EndRequest
        {
            add { AddSyncEventHookup(EventEndRequest, value, RequestNotification.EndRequest); }
            remove { RemoveSyncEventHookup(EventEndRequest, value, RequestNotification.EndRequest); }
        }

        public event EventHandler Error
        {
            add { Events.AddHandler(EventErrorRecorded, value); }
            remove { Events.RemoveHandler(EventErrorRecorded, value); }
        }

        public event EventHandler LogRequest
        {
            add { AddSyncEventHookup(EventLogRequest, value, RequestNotification.LogRequest); }
            remove { RemoveSyncEventHookup(EventLogRequest, value, RequestNotification.LogRequest); }
        }

        public event EventHandler MapRequestHandler
        {
            add { AddSyncEventHookup(EventMapRequestHandler, value, RequestNotification.MapRequestHandler); }
            remove { RemoveSyncEventHookup(EventMapRequestHandler, value, RequestNotification.MapRequestHandler); }
        }

        public event EventHandler PostAcquireRequestState
        {
            add { AddSyncEventHookup(EventPostAcquireRequestState, value, RequestNotification.AcquireRequestState, true); }
            remove { RemoveSyncEventHookup(EventPostAcquireRequestState, value, RequestNotification.AcquireRequestState, true); }
        }

        public event EventHandler PostAuthenticateRequest
        {
            add { AddSyncEventHookup(EventPostAuthenticateRequest, value, RequestNotification.AuthenticateRequest, true); }
            remove { RemoveSyncEventHookup(EventPostAuthenticateRequest, value, RequestNotification.AuthenticateRequest, true); }
        }

        public event EventHandler PostAuthorizeRequest
        {
            add { AddSyncEventHookup(EventPostAuthorizeRequest, value, RequestNotification.AuthorizeRequest, true); }
            remove { RemoveSyncEventHookup(EventPostAuthorizeRequest, value, RequestNotification.AuthorizeRequest, true); }
        }

        public event EventHandler PostLogRequest
        {
            add { AddSyncEventHookup(EventPostLogRequest, value, RequestNotification.LogRequest, true); }
            remove { RemoveSyncEventHookup(EventPostLogRequest, value, RequestNotification.LogRequest, true); }
        }

        public event EventHandler PostMapRequestHandler
        {
            add { AddSyncEventHookup(EventPostMapRequestHandler, value, RequestNotification.MapRequestHandler, true); }
            remove { RemoveSyncEventHookup(EventPostMapRequestHandler, value, RequestNotification.MapRequestHandler); }
        }

        public event EventHandler PostReleaseRequestState
        {
            add { AddSyncEventHookup(EventPostReleaseRequestState, value, RequestNotification.ReleaseRequestState, true); }
            remove { RemoveSyncEventHookup(EventPostReleaseRequestState, value, RequestNotification.ReleaseRequestState, true); }
        }

        public event EventHandler PostRequestHandlerExecute
        {
            add { AddSyncEventHookup(EventPostRequestHandlerExecute, value, RequestNotification.ExecuteRequestHandler, true); }
            remove { RemoveSyncEventHookup(EventPostRequestHandlerExecute, value, RequestNotification.ExecuteRequestHandler, true); }
        }

        public event EventHandler PostResolveRequestCache
        {
            add { AddSyncEventHookup(EventPostResolveRequestCache, value, RequestNotification.ResolveRequestCache, true); }
            remove { RemoveSyncEventHookup(EventPostResolveRequestCache, value, RequestNotification.ResolveRequestCache, true); }
        }

        public event EventHandler PostUpdateRequestCache
        {
            add { AddSyncEventHookup(EventPostUpdateRequestCache, value, RequestNotification.UpdateRequestCache, true); }
            remove { RemoveSyncEventHookup(EventPostUpdateRequestCache, value, RequestNotification.UpdateRequestCache, true); }
        }

        public event EventHandler PreRequestHandlerExecute
        {
            add { AddSyncEventHookup(EventPreRequestHandlerExecute, value, RequestNotification.PreExecuteRequestHandler); }
            remove { RemoveSyncEventHookup(EventPreRequestHandlerExecute, value, RequestNotification.PreExecuteRequestHandler); }
        }

        public event EventHandler PreSendRequestContent
        {
            add { AddSendResponseEventHookup(EventPreSendRequestContent, value); }
            remove { RemoveSendResponseEventHookup(EventPreSendRequestContent, value); }
        }

        public event EventHandler PreSendRequestHeaders
        {
            add { AddSendResponseEventHookup(EventPreSendRequestHeaders, value); }
            remove { RemoveSendResponseEventHookup(EventPreSendRequestHeaders, value); }
        }

        public event EventHandler ReleaseRequestState
        {
            add { AddSyncEventHookup(EventReleaseRequestState, value, RequestNotification.ReleaseRequestState); }
            remove { RemoveSyncEventHookup(EventReleaseRequestState, value, RequestNotification.ReleaseRequestState); }
        }

        public event EventHandler ResolveRequestCache
        {
            add { AddSyncEventHookup(EventResolveRequestCache, value, RequestNotification.ResolveRequestCache); }
            remove { RemoveSyncEventHookup(EventResolveRequestCache, value, RequestNotification.ResolveRequestCache); }
        }

        public event EventHandler UpdateRequestCache
        {
            add { AddSyncEventHookup(EventUpdateRequestCache, value, RequestNotification.UpdateRequestCache); }
            remove { RemoveSyncEventHookup(EventUpdateRequestCache, value, RequestNotification.UpdateRequestCache); }
        }

        private void AddEventMapping(string moduleName, RequestNotification requestNotification, bool isPostNotification, IExecutionStep step)
        {
            ThrowIfEventBindingDisallowed();
            //if (IsContainerInitalizationAllowed)
            //{
            //    var moduleContainer = GetModuleContainer(moduleName);
            //    if (moduleContainer != null)
            //        moduleContainer.AddEvent(requestNotification, isPostNotification, step);
            //}
        }

        public void AddOnAcquireRequestStateAsync(BeginEventHandler bh, EndEventHandler eh) { AddOnAcquireRequestStateAsync(bh, eh, null); }
        public void AddOnAcquireRequestStateAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, object state)
        {
            AsyncEvents.AddHandler(EventAcquireRequestState, beginHandler, endHandler, state, RequestNotification.AcquireRequestState, false, this);
        }

        public void AddOnAuthenticateRequestAsync(BeginEventHandler bh, EndEventHandler eh) { AddOnAuthenticateRequestAsync(bh, eh, null); }
        public void AddOnAuthenticateRequestAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, object state)
        {
            AsyncEvents.AddHandler(EventAuthenticateRequest, beginHandler, endHandler, state, RequestNotification.AuthenticateRequest, false, this);
        }

        public void AddOnAuthorizeRequestAsync(BeginEventHandler bh, EndEventHandler eh) { AddOnAuthorizeRequestAsync(bh, eh, null); }
        public void AddOnAuthorizeRequestAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, object state)
        {
            AsyncEvents.AddHandler(EventAuthorizeRequest, beginHandler, endHandler, state, RequestNotification.AuthorizeRequest, false, this);
        }

        public void AddOnBeginRequestAsync(BeginEventHandler bh, EndEventHandler eh) { AddOnBeginRequestAsync(bh, eh, null); }
        public void AddOnBeginRequestAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, object state)
        {
            AsyncEvents.AddHandler(EventBeginRequest, beginHandler, endHandler, state, RequestNotification.BeginRequest, false, this);
        }

        public void AddOnEndRequestAsync(BeginEventHandler bh, EndEventHandler eh) { AddOnEndRequestAsync(bh, eh, null); }
        public void AddOnEndRequestAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, object state)
        {
            AsyncEvents.AddHandler(EventEndRequest, beginHandler, endHandler, state, RequestNotification.EndRequest, false, this);
        }

        public void AddOnLogRequestAsync(BeginEventHandler bh, EndEventHandler eh) { AddOnLogRequestAsync(bh, eh, null); }
        public void AddOnLogRequestAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, object state)
        {
            AsyncEvents.AddHandler(EventLogRequest, beginHandler, endHandler, state, RequestNotification.LogRequest, false, this);
        }

        public void AddOnMapRequestHandlerAsync(BeginEventHandler bh, EndEventHandler eh) { AddOnMapRequestHandlerAsync(bh, eh, null); }
        public void AddOnMapRequestHandlerAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, object state)
        {
            AsyncEvents.AddHandler(EventMapRequestHandler, beginHandler, endHandler, state, RequestNotification.MapRequestHandler, false, this);
        }

        public void AddOnPostAcquireRequestStateAsync(BeginEventHandler bh, EndEventHandler eh) { AddOnPostAcquireRequestStateAsync(bh, eh, null); }
        public void AddOnPostAcquireRequestStateAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, object state)
        {
            AsyncEvents.AddHandler(EventPostAcquireRequestState, beginHandler, endHandler, state, RequestNotification.AcquireRequestState, true, this);
        }

        public void AddOnPostAuthenticateRequestAsync(BeginEventHandler bh, EndEventHandler eh) { AddOnPostAuthenticateRequestAsync(bh, eh, null); }
        public void AddOnPostAuthenticateRequestAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, object state)
        {
            AsyncEvents.AddHandler(EventPostAuthenticateRequest, beginHandler, endHandler, state, RequestNotification.AuthenticateRequest, true, this);
        }

        public void AddOnPostAuthorizeRequestAsync(BeginEventHandler bh, EndEventHandler eh) { AddOnPostAuthorizeRequestAsync(bh, eh, null); }
        public void AddOnPostAuthorizeRequestAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, object state)
        {
            AsyncEvents.AddHandler(EventPostAuthorizeRequest, beginHandler, endHandler, state, RequestNotification.AuthorizeRequest, true, this);
        }

        public void AddOnPostLogRequestAsync(BeginEventHandler bh, EndEventHandler eh) { AddOnPostLogRequestAsync(bh, eh, null); }
        public void AddOnPostLogRequestAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, object state)
        {
            AsyncEvents.AddHandler(EventPostLogRequest, beginHandler, endHandler, state, RequestNotification.LogRequest, true, this);
        }

        public void AddOnPostMapRequestHandlerAsync(BeginEventHandler bh, EndEventHandler eh) { AddOnPostMapRequestHandlerAsync(bh, eh, null); }
        public void AddOnPostMapRequestHandlerAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, object state)
        {
            AsyncEvents.AddHandler(EventPostMapRequestHandler, beginHandler, endHandler, state, RequestNotification.MapRequestHandler, true, this);
        }

        public void AddOnPostReleaseRequestStateAsync(BeginEventHandler bh, EndEventHandler eh) { AddOnPostReleaseRequestStateAsync(bh, eh, null); }
        public void AddOnPostReleaseRequestStateAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, object state)
        {
            AsyncEvents.AddHandler(EventPostReleaseRequestState, beginHandler, endHandler, state, RequestNotification.ReleaseRequestState, true, this);
        }

        public void AddOnPostRequestHandlerExecuteAsync(BeginEventHandler bh, EndEventHandler eh) { AddOnPostRequestHandlerExecuteAsync(bh, eh, null); }
        public void AddOnPostRequestHandlerExecuteAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, object state)
        {
            AsyncEvents.AddHandler(EventPostRequestHandlerExecute, beginHandler, endHandler, state, RequestNotification.ExecuteRequestHandler, true, this);
        }

        public void AddOnPostResolveRequestCacheAsync(BeginEventHandler bh, EndEventHandler eh) { AddOnPostResolveRequestCacheAsync(bh, eh, null); }
        public void AddOnPostResolveRequestCacheAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, object state)
        {
            AsyncEvents.AddHandler(EventPostResolveRequestCache, beginHandler, endHandler, state, RequestNotification.ResolveRequestCache, true, this);
        }

        public void AddOnPostUpdateRequestCacheAsync(BeginEventHandler bh, EndEventHandler eh) { AddOnPostUpdateRequestCacheAsync(bh, eh, null); }
        public void AddOnPostUpdateRequestCacheAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, object state)
        {
            AsyncEvents.AddHandler(EventPostUpdateRequestCache, beginHandler, endHandler, state, RequestNotification.UpdateRequestCache, true, this);
        }

        public void AddOnPreRequestHandlerExecuteAsync(BeginEventHandler bh, EndEventHandler eh) { AddOnPreRequestHandlerExecuteAsync(bh, eh, null); }
        public void AddOnPreRequestHandlerExecuteAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, object state)
        {
            AsyncEvents.AddHandler(EventPreRequestHandlerExecute, beginHandler, endHandler, state, RequestNotification.PreExecuteRequestHandler, false, this);
        }

        public void AddOnReleaseRequestStateAsync(BeginEventHandler bh, EndEventHandler eh) { AddOnReleaseRequestStateAsync(bh, eh, null); }
        public void AddOnReleaseRequestStateAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, object state)
        {
            AsyncEvents.AddHandler(EventReleaseRequestState, beginHandler, endHandler, state, RequestNotification.ReleaseRequestState, false, this);
        }

        public void AddOnResolveRequestCacheAsync(BeginEventHandler bh, EndEventHandler eh) { AddOnResolveRequestCacheAsync(bh, eh, null); }
        public void AddOnResolveRequestCacheAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, object state)
        {
            AsyncEvents.AddHandler(EventResolveRequestCache, beginHandler, endHandler, state, RequestNotification.ResolveRequestCache, false, this);
        }

        public void AddOnUpdateRequestCacheAsync(BeginEventHandler bh, EndEventHandler eh) { AddOnUpdateRequestCacheAsync(bh, eh, null); }
        public void AddOnUpdateRequestCacheAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, object state)
        {
            AsyncEvents.AddHandler(EventUpdateRequestCache, beginHandler, endHandler, state, RequestNotification.UpdateRequestCache, false, this);
        }

        private void AddSendResponseEventHookup(object key, Delegate handler)
        {
            ThrowIfEventBindingDisallowed();
            Events.AddHandler(key, handler);
            //if (IsContainerInitalizationAllowed)
            //{
            //    var moduleContainer = GetModuleContainer(CurrentModuleCollectionKey);
            //    if (moduleContainer != null)
            //    {
            //        bool isHeaders = key == EventPreSendRequestHeaders;
            //        var step = new SendResponseExecutionStep(this, (EventHandler)handler, isHeaders);
            //        moduleContainer.AddEvent(RequestNotification.SendResponse, false, step);
            //    }
            //}
        }

        internal void AddSyncEventHookup(object key, Delegate handler, RequestNotification notification) { AddSyncEventHookup(key, handler, notification, false); }
        private void AddSyncEventHookup(object key, Delegate handler, RequestNotification notification, bool isPostNotification)
        {
            ThrowIfEventBindingDisallowed();
            Events.AddHandler(key, handler);
            //if (IsContainerInitalizationAllowed)
            //{
            //    var moduleContainer = GetModuleContainer(CurrentModuleCollectionKey);
            //    if (moduleContainer != null)
            //    {
            //        var step = new SyncEventExecutionStep(this, (EventHandler)handler);
            //        moduleContainer.AddEvent(notification, isPostNotification, step);
            //    }
            //}
        }

        private void BuildEventMaskDictionary(Dictionary<string, RequestNotification> eventMask)
        {
            eventMask["BeginRequest"] = RequestNotification.BeginRequest;
            eventMask["AuthenticateRequest"] = RequestNotification.AuthenticateRequest;
            eventMask["PostAuthenticateRequest"] = RequestNotification.AuthenticateRequest;
            eventMask["AuthorizeRequest"] = RequestNotification.AuthorizeRequest;
            eventMask["PostAuthorizeRequest"] = RequestNotification.AuthorizeRequest;
            eventMask["ResolveRequestCache"] = RequestNotification.ResolveRequestCache;
            eventMask["PostResolveRequestCache"] = RequestNotification.ResolveRequestCache;
            eventMask["MapRequestHandler"] = RequestNotification.MapRequestHandler;
            eventMask["PostMapRequestHandler"] = RequestNotification.MapRequestHandler;
            eventMask["AcquireRequestState"] = RequestNotification.AcquireRequestState;
            eventMask["PostAcquireRequestState"] = RequestNotification.AcquireRequestState;
            eventMask["PreRequestHandlerExecute"] = RequestNotification.PreExecuteRequestHandler;
            eventMask["PostRequestHandlerExecute"] = RequestNotification.ExecuteRequestHandler;
            eventMask["ReleaseRequestState"] = RequestNotification.ReleaseRequestState;
            eventMask["PostReleaseRequestState"] = RequestNotification.ReleaseRequestState;
            eventMask["UpdateRequestCache"] = RequestNotification.UpdateRequestCache;
            eventMask["PostUpdateRequestCache"] = RequestNotification.UpdateRequestCache;
            eventMask["LogRequest"] = RequestNotification.LogRequest;
            eventMask["PostLogRequest"] = RequestNotification.LogRequest;
            eventMask["EndRequest"] = RequestNotification.EndRequest;
            eventMask["PreSendRequestHeaders"] = RequestNotification.SendResponse;
            eventMask["PreSendRequestContent"] = RequestNotification.SendResponse;
        }

        private void CreateEventExecutionSteps(object eventIndex, ArrayList steps)
        {
            var handler = AsyncEvents[eventIndex];
            if (handler != null)
                handler.CreateExecutionSteps(this, steps);
            var handler2 = (EventHandler)Events[eventIndex];
            if (handler2 != null)
            {
                var invocationList = handler2.GetInvocationList();
                for (int index = 0; index < invocationList.Length; index++)
                    steps.Add(new SyncEventExecutionStep(this, (EventHandler)invocationList[index]));
            }
        }

        private bool HasEventSubscription(object eventIndex)
        {
            bool flag = false;
            var handler = AsyncEvents[eventIndex];
            if ((handler != null) && (handler.Count > 0))
            {
                handler.Reset();
                flag = true;
            }
            var handler2 = (EventHandler)Events[eventIndex];
            if (handler2 != null)
            {
                var invocationList = handler2.GetInvocationList();
                if (invocationList.Length > 0)
                    flag = true;
                foreach (Delegate delegate2 in invocationList)
                    Events.RemoveHandler(eventIndex, delegate2);
            }
            return flag;
        }

        private void HookupEventHandlersForApplicationAndModules(MethodInfo[] handlers)
        {
            _currentModuleCollectionKey = "global.asax";
            for (int i = 0; i < handlers.Length; i++)
            {
                var arglessMethod = handlers[i];
                string name = arglessMethod.Name;
                int index = name.IndexOf('_');
                string str2 = name.Substring(0, index);
                object component = null;
                if (string.Equals(str2, "Application", StringComparison.OrdinalIgnoreCase))
                    component = this;
                else if (_moduleCollection != null)
                    component = _moduleCollection[str2];
                if (component != null)
                {
                    var componentType = component.GetType();
                    var events = TypeDescriptor.GetEvents(componentType);
                    string targetEvent = name.Substring(index + 1);
                    var descriptor = events.Find(targetEvent, true);
                    if ((descriptor == null) && string.Equals(targetEvent.Substring(0, 2), "on", StringComparison.OrdinalIgnoreCase))
                    {
                        targetEvent = targetEvent.Substring(2);
                        descriptor = events.Find(targetEvent, true);
                    }
                    MethodInfo addMethod = null;
                    if (descriptor != null)
                    {
                        var componentEvent = componentType.GetEvent(descriptor.Name);
                        if (componentEvent != null)
                            addMethod = componentEvent.GetAddMethod();
                    }
                    if (addMethod != null)
                    {
                        var parameters = addMethod.GetParameters();
                        if (parameters.Length == 1)
                        {
                            Delegate handler = null;
                            if (arglessMethod.GetParameters().Length == 0)
                            {
                                if (parameters[0].ParameterType != typeof(EventHandler))
                                    continue;
                                var proxy = new ArglessEventHandlerProxy(this, arglessMethod);
                                handler = proxy.Handler;
                            }
                            else
                            {
                                try { handler = Delegate.CreateDelegate(parameters[0].ParameterType, this, name); }
                                catch { continue; }
                            }
                            addMethod.Invoke(component, new object[] { handler });
                        }
                    }
                }
            }
        }

        private void ProcessEventSubscriptions(out RequestNotification requestNotifications, out RequestNotification postRequestNotifications)
        {
            requestNotifications = 0;
            postRequestNotifications = 0;
            if (HasEventSubscription(EventBeginRequest))
                requestNotifications |= RequestNotification.BeginRequest;
            if (HasEventSubscription(EventAuthenticateRequest))
                requestNotifications |= RequestNotification.AuthenticateRequest;
            if (HasEventSubscription(EventPostAuthenticateRequest))
                postRequestNotifications |= RequestNotification.AuthenticateRequest;
            if (HasEventSubscription(EventAuthorizeRequest))
                requestNotifications |= RequestNotification.AuthorizeRequest;
            if (HasEventSubscription(EventPostAuthorizeRequest))
                postRequestNotifications |= RequestNotification.AuthorizeRequest;
            if (HasEventSubscription(EventResolveRequestCache))
                requestNotifications |= RequestNotification.ResolveRequestCache;
            if (HasEventSubscription(EventPostResolveRequestCache))
                postRequestNotifications |= RequestNotification.ResolveRequestCache;
            if (HasEventSubscription(EventMapRequestHandler))
                requestNotifications |= RequestNotification.MapRequestHandler;
            if (HasEventSubscription(EventPostMapRequestHandler))
                postRequestNotifications |= RequestNotification.MapRequestHandler;
            if (HasEventSubscription(EventAcquireRequestState))
                requestNotifications |= RequestNotification.AcquireRequestState;
            if (HasEventSubscription(EventPostAcquireRequestState))
                postRequestNotifications |= RequestNotification.AcquireRequestState;
            if (HasEventSubscription(EventPreRequestHandlerExecute))
                requestNotifications |= RequestNotification.PreExecuteRequestHandler;
            if (HasEventSubscription(EventPostRequestHandlerExecute))
                postRequestNotifications |= RequestNotification.ExecuteRequestHandler;
            if (HasEventSubscription(EventReleaseRequestState))
                requestNotifications |= RequestNotification.ReleaseRequestState;
            if (HasEventSubscription(EventPostReleaseRequestState))
                postRequestNotifications |= RequestNotification.ReleaseRequestState;
            if (HasEventSubscription(EventUpdateRequestCache))
                requestNotifications |= RequestNotification.UpdateRequestCache;
            if (HasEventSubscription(EventPostUpdateRequestCache))
                postRequestNotifications |= RequestNotification.UpdateRequestCache;
            if (HasEventSubscription(EventLogRequest))
                requestNotifications |= RequestNotification.LogRequest;
            if (HasEventSubscription(EventPostLogRequest))
                postRequestNotifications |= RequestNotification.LogRequest;
            if (HasEventSubscription(EventEndRequest))
                requestNotifications |= RequestNotification.EndRequest;
            if (HasEventSubscription(EventPreSendRequestHeaders))
                requestNotifications |= RequestNotification.SendResponse;
            if (HasEventSubscription(EventPreSendRequestContent))
                requestNotifications |= RequestNotification.SendResponse;
        }

        internal void RaiseErrorWithoutContext(Exception error)
        {
            try
            {
                SetAppLevelCulture();
                _lastError = error;
                RaiseOnError();
            }
            finally
            {
                if (_state != null)
                    _state.EnsureUnLock();
                RestoreAppLevelCulture();
                _lastError = null;
                _appEvent = null;
            }
        }

        private void RaiseOnError()
        {
            var handler = (EventHandler)Events[EventErrorRecorded];
            if (handler != null)
            {
                try { handler(this, AppEvent); }
                catch (Exception exception)
                {
                    if (_context != null)
                        _context.AddError(exception);
                }
            }
        }

        internal void RaiseOnPreSendRequestContent()
        {
            var handler = (EventHandler)Events[EventPreSendRequestContent];
            if (handler != null)
            {
                try { handler(this, AppEvent); }
                catch (Exception exception) { RecordError(exception); }
            }
        }

        internal void RaiseOnPreSendRequestHeaders()
        {
            var handler = (EventHandler)Events[EventPreSendRequestHeaders];
            if (handler != null)
            {
                try { handler(this, AppEvent); }
                catch (Exception exception) { RecordError(exception); }
            }
        }

        //private void RegisterEventSubscriptions(NetHttpContext context, MethodInfo[] handlers)
        //{
        //    _moduleCollection = GetModuleCollection();
        //    if (handlers != null)
        //        HookupEventHandlersForApplicationAndModules(handlers);
        //    _applicationFactory.EnsureAppStartCalled(context, this);
        //    try
        //    {
        //        _hideRequestResponse = true; context.HideRequestResponse = true;
        //        _context = context;
        //        Init();
        //    }
        //    catch (Exception exception)
        //    {
        //        var error = context.Error;
        //        if (error != null)
        //            throw error;
        //    }
        //    finally
        //    {
        //        _context = null;
        //        context.HideRequestResponse = false; _hideRequestResponse = false;
        //    }
        //    //
        //    //RequestNotification notification;
        //    //RequestNotification notification2;
        //    //ProcessEventSubscriptions(out notification, out notification2);
        //    //_appRequestNotifications |= notification;
        //    //_appPostNotifications |= notification2;
        //    //for (int index = 0; index < _moduleCollection.Count; index++)
        //    //{
        //    //    _currentModuleCollectionKey = _moduleCollection.GetKey(index);
        //    //    IHttpModule module = _moduleCollection.Get(index);
        //    //    ModuleConfigurationInfo info = _moduleConfigInfo[index];
        //    //    module.Init(this);
        //    //    ProcessEventSubscriptions(out notification, out notification2);
        //    //    if ((notification != 0) || (notification2 != 0))
        //    //        RegisterIntegratedEvent(appContext, info.Name, notification, notification2, info.Type, info.Precondition, false);
        //    //}
        //    //RegisterIntegratedEvent(appContext, "ManagedPipelineHandler", RequestNotification.ExecuteRequestHandler | RequestNotification.MapRequestHandler, 0, string.Empty, string.Empty, false);
        //}

        //private void RegisterIntegratedEvent(IntPtr appContext, string moduleName, RequestNotification requestNotifications, RequestNotification postRequestNotifications, string moduleType, string modulePrecondition, bool useHighPriority)
        //{
        //    int count;
        //    if (_moduleIndexMap.ContainsKey(moduleName))
        //    {
        //        count = (int)_moduleIndexMap[moduleName];
        //    }
        //    else
        //    {
        //        count = _moduleIndexMap.Count;
        //        _moduleIndexMap[moduleName] = count;
        //    }
        //    if (UnsafeIISMethods.MgdRegisterEventSubscription(appContext, moduleName, requestNotifications, postRequestNotifications, moduleType, modulePrecondition, new IntPtr(count), useHighPriority) < 0)
        //    {
        //        throw new HttpException(SR.GetString("Failed_Pipeline_Subscription", new object[] { moduleName }));
        //    }
        //}

        private void RemoveSendResponseEventHookup(object key, Delegate handler)
        {
            ThrowIfEventBindingDisallowed();
            Events.RemoveHandler(key, handler);
            //if (IsContainerInitalizationAllowed)
            //{
            //    PipelineModuleStepContainer moduleContainer = GetModuleContainer(CurrentModuleCollectionKey);
            //    if (moduleContainer != null)
            //        moduleContainer.RemoveEvent(RequestNotification.SendResponse, false, handler);
            //}
        }

        internal void RemoveSyncEventHookup(object key, Delegate handler, RequestNotification notification) { RemoveSyncEventHookup(key, handler, notification, false); }
        internal void RemoveSyncEventHookup(object key, Delegate handler, RequestNotification notification, bool isPostNotification)
        {
            ThrowIfEventBindingDisallowed();
            Events.RemoveHandler(key, handler);
            //if (IsContainerInitalizationAllowed)
            //{
            //    var moduleContainer = GetModuleContainer(CurrentModuleCollectionKey);
            //    if (moduleContainer != null)
            //        moduleContainer.RemoveEvent(notification, isPostNotification, handler);
            //}
        }

        private void ThrowIfEventBindingDisallowed()
        {
            if (_initSpecialCompleted && _initInternalCompleted)
                throw new InvalidOperationException("Event_Binding_Disallowed");
        }

        internal EventArgs AppEvent
        {
            get
            {
                if (_appEvent == null)
                    _appEvent = EventArgs.Empty;
                return _appEvent;
            }
            set { _appEvent = null; }
        }

        private AsyncAppEventHandlersTable AsyncEvents
        {
            get
            {
                if (_asyncEvents == null)
                    _asyncEvents = new AsyncAppEventHandlersTable();
                return _asyncEvents;
            }
        }

        internal NetHttpAsyncResult AsyncResult
        {
            get { return _ar; }
            set { _ar = value; }
        }

        protected EventHandlerList Events
        {
            get
            {
                if (_events == null)
                    _events = new EventHandlerList();
                return _events;
            }
        }
    }
}
